package com.ts.api.module.match.plan.internal.qualification.strategy;

import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.base.IteratorUtils;
import com.gitee.apanlh.util.reflection.ClassConvertUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.common.constant.api.ApiEnvEnum;
import com.ts.api.common.constant.product.ProductPlanTypeEnum;
import com.ts.api.common.localcache.DistrictCache;
import com.ts.api.common.util.OpenTimeUtils;
import com.ts.api.module.api.entity.ApiUserRequest;
import com.ts.api.module.api.entity.po.ApiKeyPO;
import com.ts.api.module.api.service.ApiBizRequiredService;
import com.ts.api.module.common.entity.DistrictPO;
import com.ts.api.module.match.plan.internal.core.PlanMatchChannelType;
import com.ts.api.module.match.plan.internal.qualification.model.PlanQualification;
import com.ts.api.module.match.plan.model.AbstractPlanMatch;
import com.ts.api.module.match.plan.model.ApiPlanMatch;
import com.ts.api.module.product.entity.po.ProductPlanFieldPO;
import com.ts.api.module.product.entity.po.ProductPlanPO;
import com.ts.api.module.product.entity.qo.ProductPlanFieldQO;
import com.ts.api.module.product.entity.qo.ProductPlanQO;
import com.ts.api.module.product.service.ProductPlanFieldService;
import com.ts.api.module.product.service.ProductPlanService;
import com.ts.api.module.test.entity.TestAccountWhitelistPO;
import com.ts.api.module.test.service.TestAccountWhitelistService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 *  基础验证实现
 *
 *  @author Pan
 */
@Service
public class BaseQualification {

    @Autowired
    private ProductPlanService productPlanService;
    @Autowired
    private ProductPlanFieldService productPlanFieldService;
    @Autowired
    private ApiBizRequiredService apiBizRequiredService;
    @Autowired
    private TestAccountWhitelistService testAccountWhitelistService;

    /**
     *  验证城市地区是否存在
     *
     *  @param  planQualification    计划用户资质类
     *  @return DistrictPO
     */
    public DistrictPO validArea(PlanQualification planQualification) {
        ApiUserRequest apiUserRequest = planQualification.getApiUserRequest();
        String areaName = apiUserRequest.getCity();

        if (ValidParam.isEmpty(areaName)) {
            return null;
        }
        return DistrictCache.getByName(areaName);
    }

    /**
     *  根据计划类型及环境匹配计划
     *
     *  @param  planQualification    计划用户资质类
     *  @return List
     */
    public List<ProductPlanPO> filterPlanType(PlanQualification planQualification, AbstractPlanMatch abstractPlanMatch) {
        ApiUserRequest apiUserRequest = planQualification.getApiUserRequest();
        String areaName = apiUserRequest.getCity();

        //  查询对象
        List<Integer> listPlanType = ProductPlanTypeEnum.listPlanToListInt(planQualification.getListPlanType());
        ProductPlanQO productPlanQO = ProductPlanQO.createAreaName(areaName);
        productPlanQO.setListPlanType(listPlanType);

        PlanMatchChannelType planMatchChannelType = abstractPlanMatch.getPlanMatchChannelType();

        //  只有API渠道
        if (Eq.enumsOr(planMatchChannelType.API, PlanMatchChannelType.API_WAKE, planMatchChannelType)) {
            ApiPlanMatch apiPlanMatch = (ApiPlanMatch) abstractPlanMatch;
            ApiKeyPO apiKeyPO = apiPlanMatch.getApiKeyPO();
            productPlanQO.setEnvType(apiKeyPO.getApiEnvType());
        }

        //  自有渠道-默认全部获取正式环境计划
        if (Eq.enums(planMatchChannelType.CHANNEL, planMatchChannelType)) {
            String phone = apiUserRequest.getPhone();
            //  如果该改手机号存在测试白名单只内只匹配测试计划
            TestAccountWhitelistPO testAccountWhitelistPO = testAccountWhitelistService.get(phone);
            if (ValidParam.isNotNull(testAccountWhitelistPO)) {
                productPlanQO.setEnvType(ApiEnvEnum.TEST.getType());
            } else {
                productPlanQO.setEnvType(ApiEnvEnum.PROD.getType());
            }
        }
        //  查询计划
        return productPlanService.list(productPlanQO);
    }

    /**
     *  匹配当前时间与计划开放时间
     *
     *  @param  listProductPlan 计划集合
     *  @return List
     */
    public List<ProductPlanPO> validOpenTime(List<ProductPlanPO> listProductPlan) {
        return OpenTimeUtils.filter(listProductPlan);
    }

    /**
     *  过滤用户资质与计划资质，返回符合条件的计划列表
     *
     *  @param  listProductPlanPO           计划集合
     *  @param  apiUserRequest                 Api传输对象
     *  @return List
     */
    public List<ProductPlanPO> filterUserField(List<ProductPlanPO> listProductPlanPO, ApiUserRequest apiUserRequest) {
        //  匹配主体计划集合
        List<ProductPlanPO> listQualificationPlan = CollUtils.newArrayList();
        //  业务
        Map<String, String> userForm = ClassConvertUtils.toMapString(apiUserRequest);

        //  根据计划id分组后独立筛选符合计划
        List<ProductPlanFieldPO> listProductPlanForm = productPlanFieldService.listProductPlanField(ProductPlanFieldQO.create(listProductPlanPO));
        if (ValidParam.isEmpty(listProductPlanForm)) {
            return listProductPlanPO;
        }

        IteratorUtils.entrySet(CollUtils.groupByToLinked(listProductPlanForm, t -> t.getProductPlanId()), (planId, listPlanForm) -> {
            //  根据计划id获取计划对象
            ProductPlanPO productPlanPO = CollUtils.findOne(listProductPlanPO, t -> Eq.object(t.getId(), planId));

            //  验证资质符合
            boolean requiredPlanField = apiBizRequiredService.requiredPlanField(listPlanForm, userForm);
            if (!requiredPlanField) {
                return ;
            }
            //  添加符合计划
            listQualificationPlan.add(productPlanPO);
        });
        return listQualificationPlan;
    }

    /**
     *  过滤符合单价
     *
     *  @param  listProductPlanPO   过滤匹配集合
     *  @param  channelPrice        当前渠道单价
     *  @return List
     */
    public List<ProductPlanPO> filterPrice(List<ProductPlanPO> listProductPlanPO, BigDecimal channelPrice) {
        if (ValidParam.isEmpty(listProductPlanPO)) {
            return listProductPlanPO;
        }

        //  匹配主体计划集合
        List<ProductPlanPO> listPricePlan = CollUtils.newArrayList();

        IteratorUtils.array(listProductPlanPO, productPlanPO -> {
            //  分润模式忽略跳过
            BigDecimal share = productPlanPO.getShare();
            if (!Eq.str(share.toString(), "0.00")) {
                //  添加符合计划
                listPricePlan.add(productPlanPO);
                return ;
            }

            //  验证单价是否超过当前渠道价格-非分润模式验证
            boolean requiredPlanPrice = apiBizRequiredService.requiredPlanPrice(productPlanPO, channelPrice);
            if (!requiredPlanPrice) {
                return ;
            }
            //  添加符合计划
            listPricePlan.add(productPlanPO);
        });
        return listPricePlan;
    }

    /**
     *  过滤出已经被当前用户分发过的计划
     *
     *  @param  listProductPlanPO   计划集合
     *  @param  userId              当前用户id
     *  @return List
     */
    public List<ProductPlanPO> filterDistributeByUser(List<ProductPlanPO> listProductPlanPO, Long userId) {
        return productPlanService.filterDistributeByUser(listProductPlanPO, userId);
    }

    /**
     *  过滤当前用户已被本地crm分发过的计划
     *
     *  @param  listProductPlanPO   计划集合
     *  @param  userId              当前用户id
     *  @return List
     */
    public List<ProductPlanPO> filterDistributeLocalCrm(List<ProductPlanPO> listProductPlanPO, Long userId) {
        if (ValidParam.isEmpty(listProductPlanPO)) {
            return listProductPlanPO;
        }
        return productPlanService.filterDistributeLocalCrmByUser(listProductPlanPO, userId);
    }
}
